package com.cardone.platform.authority.service;

import com.cardone.context.CodeException;
import com.cardone.context.ContextHolder;
import com.cardone.platform.configuration.util.SiteUtils;
import com.cardone.platform.usercenter.dto.UserDto;
import com.cardone.platform.usercenter.service.UserService;
import lombok.Setter;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2014/11/4.
 */
public class ShiroDbRealm extends AuthorizingRealm {
    @Setter
    private String userFlagCode = "registration";

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        if (principals.getPrimaryPrincipal() == null || SecurityUtils.getSubject().getPrincipal() == null || !SecurityUtils.getSubject().isAuthenticated()) {
            return info;
        }

        UserDto user = (UserDto) principals.getPrimaryPrincipal();

        Map<String, List<String>> initMap = ContextHolder.getBean(RolePermissionService.class).findByUserId(user.getId(), user.getSiteId());

        if (MapUtils.isEmpty(initMap)) {
            return info;
        }

        List<String> roleCodes = initMap.get("roleCodes");

        if (CollectionUtils.isNotEmpty(roleCodes)) {
            info.addRoles(roleCodes);
        }

        List<String> permissionCodes = initMap.get("permissionCodes");

        if (CollectionUtils.isNotEmpty(permissionCodes)) {
            info.addStringPermissions(permissionCodes);
        }

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        UserDto findUser = new UserDto();

        if (StringUtils.isBlank(usernamePasswordToken.getUsername())) {
            throw new CodeException("用户名不能为空值!");
        }

        if (ArrayUtils.isEmpty(usernamePasswordToken.getPassword())) {
            throw new CodeException("密码不能为空值!");
        }

        findUser.setCode(usernamePasswordToken.getUsername());
        findUser.setFlagCode(this.userFlagCode);

        UserDto user = ContextHolder.getBean(UserService.class).login(findUser);

        if (user == null) {
            throw new CodeException("账号不存在或密码错误");
        }

        if ("2".equals(user.getValidCode())) {
            throw new CodeException("帐号锁定"); //帐号锁定
        }

        user.setHost(usernamePasswordToken.getHost());

        ByteSource byteSource = null;

        if(StringUtils.isNotBlank(user.getSalt())){
            try {
                byte[] salt = Hex.decodeHex(user.getSalt().toCharArray());

                byteSource = ByteSource.Util.bytes(salt);
            } catch (Exception ex) {
                throw new CodeException("账号不存在或密码错误");
            }
        }

        user.setSiteId(SiteUtils.readIdForContext());

        return new SimpleAuthenticationInfo(user, user.getPassword(), byteSource, getName());
    }
}
